﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using ServerLibrary.Abstract;
using ServerLibrary.Concrete;
using ServerLibrary.Infrastructure;
using System.IO.Compression;
using System.IO;
namespace ServerLibrary.Concrete
{


    /// <summary>
    /// Class which presents Task entity.
    /// </summary>
    public class Task : ITask
    {
        
        public HttpListenerRequest Request { get { return request; } set { request = value; } }

        public HttpListenerResponse Response { get { return response; } set { response = value; } }

        public IHandler FileHandler { get { return fileHandler; } set { fileHandler = value; } }


        /// <summary>
        /// Deafult constructor.
        /// </summary>
        public Task()
        {
            FileHandler = new FileHandler(Configurator.Instance.availableFormats, Configurator.Instance.DocumentsRoot);
        }


        /// <summary>
        /// Constructs task with params.
        /// </summary>
        /// <param name="request">Http request.</param>
        /// <param name="response">Http response.</param>
        /// <param name="fileHandler"> File Handler.</param>
        public Task(HttpListenerRequest request, HttpListenerResponse response, IHandler fileHandler)
        {
            this.request = request;
            this.response = response;
            this.fileHandler = fileHandler;
        }

        public void Run(object threadContext)
        {
            IHandleResult result = FileHandler.Handle(Request.Url.AbsolutePath.Replace("/", @"\"));
            switch (result.HttpStatusCode)
            {
                case 200:
                    Response.ContentType = result.ContentType;
                    string[] supportedEncodings = Request.Headers.GetValues("Accept-Encoding");
                    if (supportedEncodings.Contains("gzip"))
                    {
                        Response.AppendHeader("Content-Encoding", "gzip");
                        using (GZipStream zip = new GZipStream(response.OutputStream, CompressionMode.Compress, true))
                        {
                            zip.Write(result.File, 0, result.File.Length);
                        }
                    }
                  
                    else
                    {
                        Response.OutputStream.Write(result.File, 0, result.File.Length);
                    }                    
                    break;
                case 404:
                    Response.StatusCode = result.HttpStatusCode;
                    Response.StatusDescription = "File not found. 404";
                    result.File = Encoding.ASCII.GetBytes("<html><body><H1>File not found. 404</H1></body></html>");
                    Response.OutputStream.Write(result.File, 0, result.File.Length);
                    break;
            }
            Response.OutputStream.Close();
            OnTaskDone();
        }

        /// <summary>
        /// Raise the event
        /// </summary>
        public void OnTaskDone()
        {
            if (TaskDone != null)
            {
                TaskDone(this, null);
            }
        }


        public event TaskDoneHandler TaskDone;

        /// <summary>
        /// Contains http request.
        /// </summary>
        private HttpListenerRequest request;

        /// <summary>
        /// Contains http response.
        /// </summary>
        private HttpListenerResponse response;

        /// <summary>
        ///Contains file handler,which gets the file.
        /// </summary>
        private IHandler fileHandler;

    }
}
